package com.ssy.lingxi.marketing.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.after.sale.api.model.vo.response.ReturnGoodsTaxVO;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.common.constant.marketing.ActivityTypeEnum;
import com.ssy.lingxi.common.constant.marketing.BelongTypeEnum;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.marketing.api.model.constant.ActivityRecordTypeEnum;
import com.ssy.lingxi.marketing.api.model.constant.MkRedisKeyConstants;
import com.ssy.lingxi.marketing.api.model.request.GoodsSalesAddReq;
import com.ssy.lingxi.marketing.api.model.request.GoodsSalesItemActivityReq;
import com.ssy.lingxi.marketing.entity.activity.ActivityExecuteRecordDO;
import com.ssy.lingxi.marketing.entity.activity.ActivityGoodsDO;
import com.ssy.lingxi.marketing.entity.activity.PlatformActivitySignUpDO;
import com.ssy.lingxi.marketing.model.bo.PfActivitySignUpPageBO;
import com.ssy.lingxi.marketing.model.constant.CommonBooleanEnum;
import com.ssy.lingxi.marketing.model.constant.PlatformActivityOuterStatusEnum;
import com.ssy.lingxi.marketing.model.dto.ActivityCommonInfoDTO;
import com.ssy.lingxi.marketing.model.dto.ActivityExecuteDTO;
import com.ssy.lingxi.marketing.model.dto.ActivityExecutePageDTO;
import com.ssy.lingxi.marketing.model.vo.activity.request.*;
import com.ssy.lingxi.marketing.model.vo.activity.response.*;
import com.ssy.lingxi.marketing.model.vo.common.request.CommonIdReq;
import com.ssy.lingxi.marketing.repository.ActivityExecuteRecordRepository;
import com.ssy.lingxi.marketing.repository.ActivityGoodsRepository;
import com.ssy.lingxi.marketing.repository.PlatformActivitySignUpRepository;
import com.ssy.lingxi.marketing.service.IActivityExecuteService;
import com.ssy.lingxi.marketing.service.IMerchantActivityService;
import com.ssy.lingxi.marketing.service.IPlatformActivityService;
import com.ssy.lingxi.marketing.service.IPlatformActivitySignUpService;
import com.ssy.lingxi.marketing.service.feign.IAfterSaleFeignService;
import com.ssy.lingxi.marketing.service.feign.IOrderFeignService;
import com.ssy.lingxi.marketing.service.feign.IPlatformManageFeignService;
import com.ssy.lingxi.marketing.serviceimpl.base.activity.BaseActivityService;
import com.ssy.lingxi.marketing.utils.NumberUtil;
import com.ssy.lingxi.order.api.model.vo.response.OrderMarketingDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 活动执行服务实现类
 * 包含:能力中心、平台后台
 *
 * @author yzc
 * @version 2.0.0
 * @date 2021/8/17
 */
@Slf4j
@Service
public class ActivityExecuteServiceImpl extends BaseActivityService implements IActivityExecuteService {

    @Resource
    private IMerchantActivityService merchantActivityService;
    @Resource
    private IPlatformActivityService platformActivityService;
    @Autowired
    private IRedisStringUtils redisStringUtils;
    @Resource
    private PlatformActivitySignUpRepository signUpRepository;
    @Resource
    private IPlatformActivitySignUpService platformActivitySignUpService;
    @Resource
    private ActivityExecuteRecordRepository activityExecuteRecordRepository;
    @Resource
    private IOrderFeignService orderFeignService;
    @Resource
    private IAfterSaleFeignService afterSaleFeignService;
    @Resource
    private IPlatformManageFeignService platformManageFeignService;
    @Resource
    private ActivityGoodsRepository activityGoodsRepository;

    public List<GoodsSalesItemActivityReq> getOrderJoinActivity(String orderNo,Long skuId){
        //查缓存
        String orderKey=MkRedisKeyConstants.getOrderSkuJoinActivitiesKey(orderNo);
        String actListStr = redisStringUtils.hGet(orderKey, skuId + "", Constants.REDIS_MARKETING_INDEX);
        if(StringUtils.hasLength(actListStr)){
            return new JSONArray(actListStr).toList(GoodsSalesItemActivityReq.class);
        }
        //查库
        List<ActivityExecuteRecordDO> activityExecuteRecordDOS = activityExecuteRecordRepository.findByOrderNoAndSkuId(orderNo, skuId);
        if(CollectionUtil.isNotEmpty(activityExecuteRecordDOS)){
            return activityExecuteRecordDOS.stream().map(o ->{
                GoodsSalesItemActivityReq resp=new GoodsSalesItemActivityReq();
                resp.setActivityId(o.getActivityId());
                resp.setBelongType(o.getBelongType());
                return resp;
            }).collect(Collectors.toList());
        }
        return null;
    }

    public PageData<ActivityExecuteDTO> basePage(ActivityExecutePageDTO dto, int current, int pageSize) {
        // 组装分页参数
        Pageable page = PageRequest.of(current - 1, pageSize);
        // 组装查询条件
        Specification<ActivityExecuteRecordDO> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            //活动类型
            list.add(criteriaBuilder.equal(root.get("belongType").as(Integer.class), dto.getBelongType()));
            //活动id
            list.add(criteriaBuilder.equal(root.get("activityId").as(Long.class), dto.getActivityId()));
            //skuId
            list.add(criteriaBuilder.equal(root.get("skuId").as(Long.class), dto.getSkuId()));

            //单据类型
            if (dto.getRecordType() != null) {
                list.add(criteriaBuilder.equal(root.get("recordType").as(Integer.class), dto.getRecordType()));
            }
            //商城
            if (dto.getShopId() != null) {
                list.add(criteriaBuilder.equal(root.get("shopId").as(Long.class), dto.getShopId()));
            }
            //单据号
            if (StringUtils.hasLength(dto.getOrderNo())) {
                list.add(criteriaBuilder.equal(root.get("orderNo").as(String.class), dto.getOrderNo()));
            }
            //客户名称
            if (StringUtils.hasLength(dto.getMemberName())) {
                list.add(criteriaBuilder.like(root.get("memberName").as(String.class), "%" + dto.getMemberName().trim() + "%"));
            }
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<ActivityExecuteRecordDO> pageList = activityExecuteRecordRepository.findAll(spec, page);
        List<ActivityExecuteDTO> resultList = pageList.getContent().stream().map(o -> {
            ActivityExecuteDTO resp = new ActivityExecuteDTO();
            resp.setRecordType(o.getRecordType());
            resp.setBelongType(o.getBelongType());
            resp.setSkuId(o.getSkuId());
            resp.setShopName(o.getShopName());
            resp.setOrderId(o.getOrderId());
            resp.setOrderNo(o.getOrderNo());
            resp.setMemberId(o.getMemberId());
            resp.setMemberName(o.getMemberName());
            resp.setRoleId(o.getRoleId());
            resp.setOrderTime(o.getOrderTime());
            resp.setQuantity(o.getQuantity());
            resp.setAmount(o.getAmount());
            ActivityRecordTypeEnum activityRecordTypeEnum = ActivityRecordTypeEnum.find(o.getRecordType());
            if (activityRecordTypeEnum != null) {
                resp.setRecordTypeName(activityRecordTypeEnum.getMessage());
            }
            return resp;
        }).collect(Collectors.toList());
        return new PageData<>(pageList.getTotalElements(), resultList);
    }


    @Override
    public Wrapper<PageData<MerchantActivityExecutePageResp>> pageMerchant(UserLoginCacheDTO sysUser, MerchantActivityCommonPageVO pageReq) {
        Wrapper<PageData<MerchantActivitySummaryPageResp>> pageDataWrapper = merchantActivityService.pageSummary(sysUser, pageReq);
        List<MerchantActivityExecutePageResp> respList = null;
        List<MerchantActivitySummaryPageResp> data = pageDataWrapper.getData().getData();
        if (CollectionUtil.isNotEmpty(data)) {
            respList = data.stream().map(o -> {
                MerchantActivityExecutePageResp resp = new MerchantActivityExecutePageResp();
                resp.setId(o.getId());
                resp.setActivityName(o.getActivityName());
                resp.setActivityType(o.getActivityType());
                resp.setActivityTypeName(o.getActivityTypeName());
                resp.setStartTime(o.getStartTime());
                resp.setEndTime(o.getEndTime());
                resp.setStatus(o.getInnerStatus());
                resp.setStatusName(o.getInnerStatusName());
                //客户参与数
                String customerNumKey = MkRedisKeyConstants.getExecuteCustomerNumKey(BelongTypeEnum.MERCHANT.getCode(), o.getId());
                Long customerCount = redisStringUtils.getZSetSize(customerNumKey);
                resp.setCustomerCount(NumberUtil.setZeroOfNull(customerCount).intValue());
                //订单数与订单金额
                String orderKeyPrefix = MkRedisKeyConstants.getExecuteOrderKeyPrefix(BelongTypeEnum.MERCHANT.getCode(), o.getId());
                Map<String, String> orderMap = redisStringUtils.hGetAll(orderKeyPrefix, Constants.REDIS_MARKETING_INDEX);
                if (orderMap != null && !orderMap.isEmpty()) {
                    String orderCount = orderMap.get(Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_COUNT);
                    resp.setOrderCount(NumberUtil.strToInteger(orderCount));
                    String orderAmount = orderMap.get(Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_AMOUNT);
                    resp.setOrderAmount(NumberUtil.strToBigDecimal(orderAmount));
                } else {
                    resp.setOrderAmount(BigDecimal.ZERO);
                    resp.setOrderCount(0);
                }
                return resp;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(new PageData<>(pageDataWrapper.getData().getTotalCount(), respList));
    }

    @Override
    public Wrapper<MerchantActivityDetailResp> detailMerchant(UserLoginCacheDTO sysUser, CommonIdReq req) {
        return merchantActivityService.getBaseDetail(sysUser, req);
    }

    @Override
    public Wrapper<PageData<ActivityExecuteGoodsPageResp>> pageByActivityGoodsMerchant(UserLoginCacheDTO sysUser, PfActivityGoodsPageReq req) {
        Wrapper<PageData<McActivityGoodsPageResp>> pageDataWrapper = merchantActivityService.pageByActivityGoods(sysUser, req);
        List<ActivityExecuteGoodsPageResp> respList = null;
        List<McActivityGoodsPageResp> data = pageDataWrapper.getData().getData();
        if (CollectionUtil.isNotEmpty(data)) {
            respList = data.stream().map(o -> {
                ActivityExecuteGoodsPageResp resp = new ActivityExecuteGoodsPageResp();
                resp.setId(o.getId());
                resp.setActivityId(o.getActivityId());
                resp.setMemberId(o.getMemberId());
                resp.setMemberName(o.getMemberName());
                resp.setRoleId(o.getRoleId());
                resp.setRoleName(o.getRoleName());
                resp.setProductId(o.getProductId());
                resp.setSkuId(o.getSkuId());
                resp.setProductName(o.getProductName());
                resp.setType(o.getType());
                resp.setCategory(o.getCategory());
                resp.setBrand(o.getBrand());
                resp.setUnit(o.getUnit());
                resp.setPrice(o.getPrice());
                resp.setPreSelPrice(o.getPreSelPrice());
                resp.setPlummetPrice(o.getPlummetPrice());
                resp.setActivityPrice(o.getActivityPrice());
                resp.setDeductionPrice(o.getDeductionPrice());
                resp.setDiscount(o.getDiscount());
                resp.setRestrictNum(o.getRestrictNum());
                resp.setRestrictTotalNum(o.getRestrictTotalNum());
                resp.setProductImgUrl(o.getProductImgUrl());
                resp.setGoodsSubsidiaryGroupList(o.getGoodsSubsidiaryGroupList());
                resp.setCouponGroupList(o.getCouponGroupList());
                //sku客户参与数
                String activitySkuCustomerNumKey = MkRedisKeyConstants.getActivitySkuCustomerNumKey(BelongTypeEnum.MERCHANT.getCode(), o.getActivityId(), o.getSkuId());
                Long customerCount = redisStringUtils.getZSetSize(activitySkuCustomerNumKey);
                resp.setCustomerCount(NumberUtil.setZeroOfNull(customerCount).intValue());
                //订单数与订单金额
                resp.setAmount(o.getSalesAmount().add(o.getRefundAmount()));
                resp.setSalesNum(o.getSalesNum().add(o.getRefundNum()));
                return resp;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(new PageData<>(pageDataWrapper.getData().getTotalCount(), respList));
    }

    @Override
    public Wrapper<PageData<PlatformActivityExecuteAbilityPageResp>> pagePlatformOfAbility(UserLoginCacheDTO sysUser, PfActivitySignUpPageReq pageReq) {
        PageData<PfActivitySignUpPageBO> pageDataWrapper = platformActivitySignUpService.pageExecuteByMerchant(sysUser, pageReq);
        List<PlatformActivityExecuteAbilityPageResp> respList = null;
        List<PfActivitySignUpPageBO> data = pageDataWrapper.getData();
        if (CollectionUtil.isNotEmpty(data)) {
            //查询报名时间
            List<Long> activityIds = data.stream().map(PfActivitySignUpPageBO::getActivityId).collect(Collectors.toList());
            List<PlatformActivitySignUpDO> signUpDOS = signUpRepository.findByPlatformActivityIdInAndMemberIdAndRoleId(activityIds, sysUser.getMemberId(), sysUser.getMemberRoleId());
            Map<Long, PlatformActivitySignUpDO> signUpDOMap = signUpDOS.stream().collect(Collectors.toMap(k -> k.getPlatformActivity().getId(), v -> v, (v1, v2) -> v1));
            respList = data.stream().map(o -> {
                PlatformActivityExecuteAbilityPageResp resp = new PlatformActivityExecuteAbilityPageResp();
                resp.setId(o.getActivityId());
                resp.setActivityName(o.getActivityName());
                resp.setActivityType(o.getActivityType());
                resp.setActivityTypeName(ActivityTypeEnum.getMessage(o.getActivityType()));
                resp.setStartTime(o.getStartTime());
                resp.setEndTime(o.getEndTime());
                resp.setStatus(o.getActivityOuterStatus());
                resp.setStatusName(PlatformActivityOuterStatusEnum.getMessage(o.getActivityOuterStatus()));
                //报名时间
                PlatformActivitySignUpDO signUpDO = signUpDOMap.get(o.getActivityId());
                if (signUpDO != null) {
                    resp.setSignupTime(signUpDO.getCreateTime());
                    resp.setSignupId(signUpDO.getId());
                }
                //客户参与数
                String customerNumKey = MkRedisKeyConstants.getPfExecuteCustomerNumKey(BelongTypeEnum.PLATFORM.getCode(), o.getActivityId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
                Long customerCount = redisStringUtils.getZSetSize(customerNumKey);
                resp.setCustomerCount(NumberUtil.setZeroOfNull(customerCount).intValue());
                //订单数与订单金额
                String orderKeyPrefix = MkRedisKeyConstants.getPfExecuteOrderKeyPrefix(BelongTypeEnum.PLATFORM.getCode(), o.getActivityId(), sysUser.getMemberId(), sysUser.getMemberRoleId());
                Map<String, String> orderMap = redisStringUtils.hGetAll(orderKeyPrefix, Constants.REDIS_MARKETING_INDEX);
                if (orderMap != null && !orderMap.isEmpty()) {
                    String orderCount = orderMap.get(Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_COUNT);
                    resp.setOrderCount(NumberUtil.strToInteger(orderCount));
                    String orderAmount = orderMap.get(Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_AMOUNT);
                    resp.setOrderAmount(NumberUtil.strToBigDecimal(orderAmount));
                } else {
                    resp.setOrderAmount(BigDecimal.ZERO);
                    resp.setOrderCount(0);
                }
                return resp;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(new PageData<>(pageDataWrapper.getTotalCount(), respList));
    }

    @Override
    public Wrapper<PlatformActivityDetailResp> detailPlatformOfAbility(UserLoginCacheDTO sysUser, CommonIdReq req) {
        return platformActivityService.getBasedetail(sysUser, req);
    }

    @Override
    public Wrapper<PageData<ActivityExecuteGoodsPageResp>> pageByActivityGoodsPlatformOfAbility(UserLoginCacheDTO sysUser, PfActivityGoodsPageReq req) {
        Wrapper<PageData<PfActivitySignUpGoodsPageResp>> pageDataWrapper = platformActivityService.pageByActivityGoods(sysUser, req);
        List<ActivityExecuteGoodsPageResp> respList = null;
        List<PfActivitySignUpGoodsPageResp> data = pageDataWrapper.getData().getData();
        if (CollectionUtil.isNotEmpty(data)) {
            respList = data.stream().map(o -> {
                ActivityExecuteGoodsPageResp resp = new ActivityExecuteGoodsPageResp();
                resp.setId(o.getId());
                resp.setActivityId(o.getActivityId());
                resp.setMemberId(o.getMemberId());
                resp.setMemberName(o.getMemberName());
                resp.setRoleId(o.getRoleId());
                resp.setRoleName(o.getRoleName());
                resp.setProductId(o.getProductId());
                resp.setSkuId(o.getSkuId());
                resp.setProductName(o.getProductName());
                resp.setType(o.getType());
                resp.setCategory(o.getCategory());
                resp.setBrand(o.getBrand());
                resp.setUnit(o.getUnit());
                resp.setPrice(o.getPrice());
                resp.setPreSelPrice(o.getPreSelPrice());
                resp.setPlummetPrice(o.getPlummetPrice());
                resp.setActivityPrice(o.getActivityPrice());
                resp.setDeductionPrice(o.getDeductionPrice());
                resp.setDiscount(o.getDiscount());
                resp.setRestrictNum(o.getRestrictNum());
                resp.setRestrictTotalNum(o.getRestrictTotalNum());
                resp.setProductImgUrl(o.getProductImgUrl());
                resp.setGoodsSubsidiaryGroupList(o.getGoodsSubsidiaryGroupList());
                resp.setCouponGroupList(o.getCouponGroupList());
                //sku客户参与数
                String activitySkuCustomerNumKey = MkRedisKeyConstants.getActivitySkuCustomerNumKey(BelongTypeEnum.PLATFORM.getCode(), o.getActivityId(), o.getSkuId());
                Long customerCount = redisStringUtils.getZSetSize(activitySkuCustomerNumKey);
                resp.setCustomerCount(NumberUtil.setZeroOfNull(customerCount).intValue());
                //订单数与订单金额
                resp.setAmount(o.getSalesAmount().add(o.getRefundAmount()));
                resp.setSalesNum(o.getSalesNum().add(o.getRefundNum()));
                return resp;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(new PageData<>(pageDataWrapper.getData().getTotalCount(), respList));

    }

    private ActivityExecutePageDTO buildActivityExecutePageDTO(ActivityExecutePageReq req) {
        ActivityExecutePageDTO dto = new ActivityExecutePageDTO();
        dto.setActivityId(req.getActivityId());
        dto.setBelongType(req.getBelongType());
        dto.setSkuId(req.getSkuId());
        dto.setShopId(req.getShopId());
        dto.setOrderNo(req.getOrderNo());
        dto.setMemberName(req.getMemberName());
        dto.setStartTime(req.getStartTime());
        dto.setEndTime(req.getEndTime());
        return dto;
    }

    private ActivityExecuteDetailPageResp buildActivityExecuteDetailPageResp(ActivityExecuteDTO req) {
        ActivityExecuteDetailPageResp dto = new ActivityExecuteDetailPageResp();
        dto.setOrderId(req.getOrderId());
        dto.setOrderNo(req.getOrderNo());
        dto.setRecordType(req.getRecordType());
        dto.setRecordTypeName(req.getRecordTypeName());
        dto.setSkuId(req.getSkuId());
        dto.setShopName(req.getShopName());
        dto.setOrderNo(req.getOrderNo());
        dto.setMemberName(req.getMemberName());
        dto.setOrderTime(req.getOrderTime());
        dto.setAmount(req.getAmount());
        dto.setQuantity(req.getQuantity());
        return dto;
    }

    private Map<String, Set<Long>> convertActivityExecuteDetailPageResp(List<ActivityExecuteDetailPageResp> respList) {
        Map<String, Set<Long>> map = new HashMap<>();
        Set<Long> orderIds = null, refundIds = null, skuIds = null, refundSkuIds = null;
        for (ActivityExecuteDetailPageResp resp : respList) {
            if (ActivityRecordTypeEnum.ORDER.getCode().equals(resp.getRecordType())) {
                if (orderIds == null) {
                    orderIds = new HashSet<>();
                }
                orderIds.add(resp.getOrderId());
                if (skuIds == null) {
                    skuIds = new HashSet<>();
                }
                skuIds.add(resp.getSkuId());
            } else if (ActivityRecordTypeEnum.REFUND.getCode().equals(resp.getRecordType())) {
                if (refundIds == null) {
                    refundIds = new HashSet<>();
                }
                refundIds.add(resp.getOrderId());
                if (refundSkuIds == null) {
                    refundSkuIds = new HashSet<>();
                }
                refundSkuIds.add(resp.getSkuId());
            }
        }
        map.put("order", orderIds);
        map.put("orderSku", skuIds);
        map.put("refund", refundIds);
        map.put("refundSku", refundSkuIds);
        return map;
    }

    @Override
    public Wrapper<PageData<ActivityExecuteDetailPageResp>> pageMerchantExecuteDetailOfAbility(UserLoginCacheDTO sysUser, ActivityExecutePageReq req) {
        List<ActivityExecuteDetailPageResp> respList = null;
        PageData<ActivityExecuteDTO> activityExecuteDTOPageData = basePage(buildActivityExecutePageDTO(req), req.getCurrent(), req.getPageSize());
        if (activityExecuteDTOPageData.getTotalCount() > 0) {
            respList = activityExecuteDTOPageData.getData().stream().map(o -> buildActivityExecuteDetailPageResp(o)).collect(Collectors.toList());
            Set<Integer> recordTypeSet = respList.stream().map(ActivityExecuteDetailPageResp::getRecordType).collect(Collectors.toSet());
            Map<String, Set<Long>> reqMap = convertActivityExecuteDetailPageResp(respList);

            if (recordTypeSet.contains(ActivityRecordTypeEnum.ORDER.getCode())) {
                //调用订单接口，查询订单状态等信息
                Map<String, OrderMarketingDetailVO> orderInfoMapByExecute = orderFeignService.getOrderInfoMapByExecute(new ArrayList<>(reqMap.get("order")), new ArrayList<>(reqMap.get("orderSku")));
                for (ActivityExecuteDetailPageResp r : respList) {
                    OrderMarketingDetailVO detailVO = orderInfoMapByExecute.get(r.getOrderId() + ":" + r.getSkuId());
                    if (detailVO != null) {
                        r.setSkuPrice(detailVO.getAmount());
                        r.setIsHasTax(CommonBooleanEnum.toInteger(detailVO.getHasTax()));
                        r.setTaxRate(NumberUtil.multiplyHundred(detailVO.getTaxRate()).doubleValue());
                        r.setStatusName(detailVO.getOuterStatusName());
                    }
                }
            } else if (recordTypeSet.contains(ActivityRecordTypeEnum.REFUND.getCode())) {
                //调用售后接口，查询售后订单状态等信息
                Map<String, ReturnGoodsTaxVO> orderInfoMapByExecute = afterSaleFeignService.getOrderInfoMapByExecute(new ArrayList<>(reqMap.get("refund")), new ArrayList<>(reqMap.get("refundSku")));
                for (ActivityExecuteDetailPageResp r:respList){
                    ReturnGoodsTaxVO detailVO = orderInfoMapByExecute.get(r.getOrderId() + ":" + r.getSkuId());
                    if(detailVO!=null){
                        //r.setSkuPrice(detailVO.getAmount());
                        r.setIsHasTax(CommonBooleanEnum.toInteger(detailVO.getHasTax()));
                        r.setTaxRate(NumberUtil.multiplyHundred(detailVO.getTaxRate()).doubleValue());
                        r.setStatusName(detailVO.getOuterStatusName());
                    }
                }

            }
        }
        return Wrapper.success(new PageData<>(activityExecuteDTOPageData.getTotalCount(), respList));
    }

    @Override
    public Wrapper<PageData<PlatformActivityExecutePageResp>> pagePlatform(UserLoginCacheDTO sysUser, PlatformActivityPageReq pageReq) {
        Wrapper<PageData<PlatformActivitySummaryPageResp>> pageDataWrapper = platformActivityService.pageSummary(null, pageReq);
        List<PlatformActivityExecutePageResp> respList = null;
        List<PlatformActivitySummaryPageResp> data = pageDataWrapper.getData().getData();
        if (CollectionUtil.isNotEmpty(data)) {
            //查询报名时间
            List<Long> activityIds = data.stream().map(PlatformActivitySummaryPageResp::getId).collect(Collectors.toList());
            List<PlatformActivitySignUpDO> signUpDOS = signUpRepository.findByPlatformActivityIdInAndMemberIdAndRoleId(activityIds, sysUser.getMemberId(), sysUser.getMemberRoleId());
            Map<Long, PlatformActivitySignUpDO> signUpDOMap = signUpDOS.stream().collect(Collectors.toMap(k -> k.getPlatformActivity().getId(), v -> v, (v1, v2) -> v1));
            respList = data.stream().map(o -> {
                PlatformActivityExecutePageResp resp = new PlatformActivityExecutePageResp();
                resp.setId(o.getId());
                resp.setActivityName(o.getActivityName());
                resp.setActivityType(o.getActivityType());
                resp.setActivityTypeName(ActivityTypeEnum.getMessage(o.getActivityType()));
                resp.setStartTime(o.getStartTime());
                resp.setEndTime(o.getEndTime());
                resp.setStatus(o.getOuterStatus());
                resp.setStatusName(PlatformActivityOuterStatusEnum.getMessage(o.getOuterStatus()));
                //报名时间
                PlatformActivitySignUpDO signUpDO = signUpDOMap.get(o.getId());
                if (signUpDO != null) {
                    resp.setSignupTime(signUpDO.getCreateTime());
                }
                //客户参与数
                String customerNumKey = MkRedisKeyConstants.getPfExecuteCustomerNumKey(BelongTypeEnum.PLATFORM.getCode(), o.getId(),null,null);
                Long customerCount = redisStringUtils.getZSetSize(customerNumKey);
                resp.setCustomerCount(NumberUtil.setZeroOfNull(customerCount).intValue());
                //订单数与订单金额
                String orderKeyPrefix = MkRedisKeyConstants.getPfExecuteOrderKeyPrefix(BelongTypeEnum.PLATFORM.getCode(), o.getId(), null,null);
                Map<String, String> orderMap = redisStringUtils.hGetAll(orderKeyPrefix, Constants.REDIS_MARKETING_INDEX);
                if (orderMap != null && !orderMap.isEmpty()) {
                    String orderCount = orderMap.get(Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_COUNT);
                    resp.setOrderCount(NumberUtil.strToInteger(orderCount));
                    String orderAmount = orderMap.get(Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_AMOUNT);
                    resp.setOrderAmount(NumberUtil.strToBigDecimal(orderAmount));
                } else {
                    resp.setOrderAmount(BigDecimal.ZERO);
                    resp.setOrderCount(0);
                }
                return resp;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(new PageData<>(pageDataWrapper.getData().getTotalCount(), respList));
    }

    @Override
    public Wrapper<PlatformActivityDetailResp> detailPlatform(UserLoginCacheDTO sysUser, CommonIdReq req) {
        return platformActivityService.getBasedetail(sysUser, req);
    }

    @Override
    public Wrapper<PageData<ActivityExecuteGoodsPageResp>> pageByActivityGoodsPlatform(UserLoginCacheDTO sysUser, PfActivityGoodsPageReq req) {
        Wrapper<PageData<PfActivitySignUpGoodsPageResp>> pageDataWrapper = platformActivityService.pageByActivityGoods(null, req);
        List<ActivityExecuteGoodsPageResp> respList = null;
        List<PfActivitySignUpGoodsPageResp> data = pageDataWrapper.getData().getData();
        if (CollectionUtil.isNotEmpty(data)) {
            respList = data.stream().map(o -> {
                ActivityExecuteGoodsPageResp resp = new ActivityExecuteGoodsPageResp();
                resp.setId(o.getId());
                resp.setActivityId(o.getActivityId());
                resp.setMemberId(o.getMemberId());
                resp.setMemberName(o.getMemberName());
                resp.setRoleId(o.getRoleId());
                resp.setRoleName(o.getRoleName());
                resp.setProductId(o.getProductId());
                resp.setSkuId(o.getSkuId());
                resp.setProductName(o.getProductName());
                resp.setType(o.getType());
                resp.setCategory(o.getCategory());
                resp.setBrand(o.getBrand());
                resp.setUnit(o.getUnit());
                resp.setRestrictNum(o.getRestrictNum());
                resp.setRestrictTotalNum(o.getRestrictTotalNum());
                resp.setProductImgUrl(o.getProductImgUrl());
                //价格相关
                resp.setPrice(o.getPrice());
                resp.setPreSelPrice(o.getPreSelPrice());
                resp.setPlummetPrice(o.getPlummetPrice());
                resp.setActivityPrice(o.getActivityPrice());
                resp.setDeductionPrice(o.getDeductionPrice());
                resp.setDiscount(o.getDiscount());
                //sku客户参与数
                String activitySkuCustomerNumKey = MkRedisKeyConstants.getActivitySkuCustomerNumKey(BelongTypeEnum.PLATFORM.getCode(), req.getActivityId(), o.getSkuId());
                Long customerCount = redisStringUtils.getZSetSize(activitySkuCustomerNumKey);
                resp.setCustomerCount(NumberUtil.setZeroOfNull(customerCount).intValue());
                //订单数与订单金额
                resp.setAmount(o.getSalesAmount().add(o.getRefundAmount()));
                resp.setSalesNum(o.getSalesNum().add(o.getRefundNum()));
                return resp;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(new PageData<>(pageDataWrapper.getData().getTotalCount(), respList));
    }

    public void updateActivityGoodsSales(GoodsSalesAddReq req) {
        ActivityGoodsDO activityGoodsDO = activityGoodsRepository.findByBelongTypeAndActivityIdAndSkuId(req.getBelongType(), req.getActivityId(), req.getSkuId());
        if(activityGoodsDO==null){
            log.error("更新活动商品销量错误,活动商品不存在 req:{}", JSONUtil.toJsonStr(req));
            return;
        }

        if(ActivityRecordTypeEnum.REFUND.getCode().equals(req.getRecordType())){
            BigDecimal orgiRefundNum = NumberUtil.setZeroOfNull(activityGoodsDO.getRefundNum());
            activityGoodsDO.setRefundNum(orgiRefundNum.add(BigDecimal.valueOf(req.getNum())));
            BigDecimal orgiRefundAmount = NumberUtil.setZeroOfNull(activityGoodsDO.getRefundAmount());
            activityGoodsDO.setRefundAmount(orgiRefundAmount.add(BigDecimal.valueOf(req.getAmount())));
        }else{
            BigDecimal orgiSalesNum = NumberUtil.setZeroOfNull(activityGoodsDO.getSalesNum());
            activityGoodsDO.setSalesNum(orgiSalesNum.add(BigDecimal.valueOf(req.getNum())));
            BigDecimal orgiSalesAmount = NumberUtil.setZeroOfNull(activityGoodsDO.getSalesAmount());
            activityGoodsDO.setSalesAmount(orgiSalesAmount.add(BigDecimal.valueOf(req.getAmount())));
        }

        activityGoodsRepository.saveAndFlush(activityGoodsDO);

        //保存活动执行信息
        saveActivityExecuteRecordDO(req,activityGoodsDO.getProductId());

        //缓存客户参与数、总执行金额
        cacheExecute(req,activityGoodsDO.getMemberId(),activityGoodsDO.getRoleId());
    }

    /**
     *
     * @param req
     * @param merchantMemberId 活动商品，供应商会员id
     * @param merchantRoleId 活动商品，供应商角色id
     */
    private void cacheExecute(GoodsSalesAddReq req,Long merchantMemberId,Long merchantRoleId) {
        //1.1更新活动参与客户数 db_index默认0
        Boolean actCustomer = redisStringUtils.addZSet(MkRedisKeyConstants.getExecuteCustomerNumKey(req.getBelongType(), req.getActivityId()), req.getMemberId() + ":" + req.getRoleId(), 0D);
        if (actCustomer==null||!actCustomer) {
            log.warn("更新活动参与客户数失败：item:{}", JSONUtil.toJsonStr(req));
        }
        //1.2更新活动订单数 db_index=11 (取消订单，减去1)
        boolean isOrderReq = ActivityRecordTypeEnum.ORDER.getCode().equals(req.getRecordType());
        int orderIncreateNum = req.getNum() > 0 ? 1 : -1;
        if(isOrderReq) {
            redisStringUtils.hIncrement(MkRedisKeyConstants.getExecuteOrderKeyPrefix(req.getBelongType(), req.getActivityId()), Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_COUNT, orderIncreateNum, Constants.REDIS_MARKETING_INDEX);
        }
        //1.3更新活动执行金额 db_index=11
        redisStringUtils.hIncrement(MkRedisKeyConstants.getExecuteOrderKeyPrefix(req.getBelongType(), req.getActivityId()),Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_AMOUNT,req.getAmount() , Constants.REDIS_MARKETING_INDEX);

        //1.3更新活动商品参与客户数
        Boolean skuCustomer = redisStringUtils.addZSet(MkRedisKeyConstants.getActivitySkuCustomerNumKey(req.getBelongType(), req.getActivityId(), req.getSkuId()), req.getMemberId() + ":" + req.getRoleId(), 0D);
        if (skuCustomer==null||!skuCustomer) {
            log.warn("更新活动商品参与客户数失败：item:{}", JSONUtil.toJsonStr(req));
        }

        //平台活动-保存商家活动级-汇总数据
        if(req.getBelongType().equals(BelongTypeEnum.PLATFORM.getCode())){
            //2.1更新商家参与的平台活动客户数
            String merchantCustomerNumKey=MkRedisKeyConstants.getPfExecuteCustomerNumKey(req.getBelongType(), req.getActivityId(),merchantMemberId,merchantRoleId);
            Boolean merchantCustomer =redisStringUtils.addZSet(merchantCustomerNumKey,req.getMemberId()+":"+req.getRoleId(),0D);
            if (merchantCustomer==null||!merchantCustomer) {
                log.warn("更新平台活动参与客户数失败：item:{}", JSONUtil.toJsonStr(req));
            }
            //2.2更新商家参与的平台活动执行金额 db_index=11
            redisStringUtils.hIncrement(MkRedisKeyConstants.getPfExecuteOrderKeyPrefix(req.getBelongType(), req.getActivityId(),merchantMemberId,merchantRoleId),Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_AMOUNT,req.getAmount() , Constants.REDIS_MARKETING_INDEX);
            //2.3更新商家参与的平台活动已执行订单数 db_index=11 (取消订单，减去1)
            if(isOrderReq) {
                redisStringUtils.hIncrement(MkRedisKeyConstants.getPfExecuteOrderKeyPrefix(req.getBelongType(), req.getActivityId(),merchantMemberId,merchantRoleId),Constants.REDIS_KEY_MARKETING_ACTIVITY_EXECUTE_ORDER_COUNT,orderIncreateNum , Constants.REDIS_MARKETING_INDEX);
            }
        }
    }

    public void saveActivityExecuteRecordDO(GoodsSalesAddReq req,Long productId){
        ActivityCommonInfoDTO activityInfo = getActivityInfo(req.getBelongType(), req.getActivityId());
        if(activityInfo==null){
            log.warn("保存活动执行失败,活动信息不存在 req: ", JSONUtil.toJsonStr(req));
            return;
        }
        //保存活动执行数据
        ActivityExecuteRecordDO executeRecordDO=new ActivityExecuteRecordDO();
        executeRecordDO.setShopId(req.getShopId());
        executeRecordDO.setShopName(req.getShopName());
        if(ActivityRecordTypeEnum.ORDER.getCode().equals(req.getRecordType())){
            //取消订单
            if(req.getNum()<0){
                ActivityExecuteRecordDO orgExecuteDO = activityExecuteRecordRepository.findByOrderNoAndSkuIdAndBelongTypeAndActivityId(req.getOrderNo(), req.getSkuId(),req.getBelongType(),req.getActivityId());
                if(orgExecuteDO!=null) {
                    //更新执行记录状态
                    orgExecuteDO.setStatus(0);
                    activityExecuteRecordRepository.saveAndFlush(orgExecuteDO);
                    return;
                }
            }
        }else{
            //售后订单，查询原订单的商城名称
            ActivityExecuteRecordDO orgExecuteDO = activityExecuteRecordRepository.findByOrderNoAndSkuIdAndBelongTypeAndActivityId(req.getOrderNo(), req.getSkuId(),req.getBelongType(),req.getActivityId());
            if(orgExecuteDO!=null){
                executeRecordDO.setShopId(orgExecuteDO.getShopId());
                executeRecordDO.setShopName(orgExecuteDO.getShopName());
            }
        }
        executeRecordDO.setRecordType(req.getRecordType());
        executeRecordDO.setActivityId(req.getActivityId());
        executeRecordDO.setActivityType(activityInfo.getActivityType());
        executeRecordDO.setBelongType(req.getBelongType());
        executeRecordDO.setQuantity(BigDecimal.valueOf(req.getNum()));
        executeRecordDO.setAmount(BigDecimal.valueOf(req.getAmount()));
        executeRecordDO.setMemberId(req.getMemberId());
        executeRecordDO.setRoleId(req.getRoleId());
        executeRecordDO.setOrderId(req.getOrderId());
        executeRecordDO.setOrderTime(req.getOrderTime());
        executeRecordDO.setOrderNo(req.getOrderNo());
        executeRecordDO.setOriginOrderNo(req.getOriginOrderNo());
        executeRecordDO.setMemberName(req.getMemberName());
        executeRecordDO.setProductId(productId);
        executeRecordDO.setSkuId(req.getSkuId());
        activityExecuteRecordRepository.saveAndFlush(executeRecordDO);
    }
}
